package com.talent.service.impl;

import com.talent.handler.BaseException;
import com.talent.mapper.MenuMapper;
import com.talent.pojo.dto.MenuDTO;
import com.talent.pojo.entity.Menu;
import com.talent.pojo.entity.MenuContent;
import com.talent.pojo.vo.MenuTreeVO;
import com.talent.pojo.vo.MenuContentDetailVO;
import com.talent.service.MenuService;
import com.talent.service.OperationLogService;
import com.talent.utils.ExcelUtil;
import com.talent.utils.OperationLogUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 菜单服务实现类
 */
@Service
@Slf4j
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private OperationLogService operationLogService;

    @Override
    public List<MenuTreeVO> getMenuTree(String name) {
        // 查询所有菜单
        List<Menu> allMenus = menuMapper.selectAll();
        List<Long> menuIds = new ArrayList<>();
        List<Long> parentMenuIds = new ArrayList<>();
        List<Long> contentIds = new ArrayList<>();
        // 如果有name参数，对菜单进行筛选
        if (name != null && !name.trim().isEmpty()) {
            for (Menu menu : allMenus) {
                if("CONTENT".equals(menu.getType()) && menu.getName().contains(name)) {
                    parentMenuIds.add(menu.getParentId());
                    contentIds.add(menu.getId());
                } else if ("SUBMENU".equals(menu.getType()) &&( menu.getName().contains(name) ||
                        parentMenuIds.contains(menu.getId()))) {
                    parentMenuIds.add(menu.getId());
                    menuIds.add(menu.getParentId());
                } else if ("MENU".equals(menu.getType()) && menu.getName().contains(name)) {
                    menuIds.add(menu.getId());
                }
            }
        }
        List<Long> contentMenuIds = allMenus.stream()
                .filter(menu -> "CONTENT".equals(menu.getType()))
                .map(Menu::getId)
                .collect(Collectors.toList());
        // 获取所有CONTENT类型菜单的内容详情
        Map<Long, MenuContent> contentMap = Map.of();
        if (!contentMenuIds.isEmpty()) {
            List<MenuContent> contents = menuMapper.getContentByMenuIds(contentMenuIds);
            contentMap = contents.stream()
                    .collect(Collectors.toMap(MenuContent::getMenuId, content -> content));
        }
        
        // 构建树形结构
        return buildMenuTree(allMenus, contentMap, null,contentIds,parentMenuIds,menuIds,name);
    }

    /**
     * 构建菜单树形结构
     */
    private List<MenuTreeVO> buildMenuTree(List<Menu> allMenus, Map<Long, MenuContent> contentMap, Long parentId,List<Long> contentIds,List<Long> parentMenuIds,List<Long> menuIds,String name) {
        List<MenuTreeVO> result = new ArrayList<>();
        if(parentMenuIds.isEmpty() && menuIds.isEmpty() && contentIds.isEmpty() && name != null && !name.trim().isEmpty()){
            return result;
        }
        for (Menu menu : allMenus) {
            if ((parentId == null && menu.getParentId() == null) ||
                (parentId != null && parentId.equals(menu.getParentId()))) {

                MenuTreeVO menuTreeVO = new MenuTreeVO();
                BeanUtils.copyProperties(menu, menuTreeVO);
                // 如果是CONTENT类型，添加内容详情
                if ("CONTENT".equals(menu.getType())) {
                    if(name != null && !name.trim().isEmpty() && !menu.getName().contains(name)) {
                        if(!contentIds.isEmpty()) {
                        continue;
                        }
                    }
                    MenuContent content = contentMap.get(menu.getId());
                    menuTreeVO.setContentDetails(content);
                }
                else if ("SUBMENU".equals(menu.getType())) {
                    if (name != null && !name.trim().isEmpty() && !parentMenuIds.isEmpty() && !parentMenuIds.contains(menu.getId()) && !menu.getName().contains(name)) {
                        continue;
                    }
                }else{
                    if(!menuIds.isEmpty() && !menuIds.contains(menu.getId())){
                        continue;
                    }
                }
                // 递归构建子菜单
                List<MenuTreeVO> children = buildMenuTree(allMenus, contentMap, menu.getId(),contentIds,parentMenuIds, menuIds,name);
                if (!children.isEmpty()) {
                    menuTreeVO.setChildren(children);
                }
                
                result.add(menuTreeVO);
            }
        }
        
        // 按sortOrder排序
        result.sort((a, b) -> {
            int sortA = a.getSortOrder() != null ? a.getSortOrder() : 0;
            int sortB = b.getSortOrder() != null ? b.getSortOrder() : 0;
            return Integer.compare(sortA, sortB);
        });
        
        return result;
    }

    @Override
    public Menu getById(Long id) {
        Menu menu = menuMapper.getById(id);
        if (menu == null) {
            throw new BaseException("菜单不存在");
        }
        return menu;
    }

    @Override
    @Transactional
    public Menu create(MenuDTO menuDTO) {
        // 验证父菜单是否存在
        if (menuDTO.getParentId() != null) {
            Menu parentMenu = menuMapper.getById(menuDTO.getParentId());
            if (parentMenu == null) {
                throw new BaseException("父菜单不存在");
            }
            
            // 验证层级限制
            validateMenuLevel(parentMenu, menuDTO.getType());
        }

        // 创建菜单
        Menu menu = new Menu();
        BeanUtils.copyProperties(menuDTO, menu);
        
        // 设置默认值
        if("CONTENT".equals(menuDTO.getType()) && menu.getSortOrder() == null) {
            menu.setSortOrder(2);
        }
        if("SUBMENU".equals(menuDTO.getType()) && menu.getSortOrder() == null) {
            menu.setSortOrder(1);
        }
        if("MENU".equals(menuDTO.getType()) && menu.getSortOrder() == null) {
            menu.setSortOrder(0);
        }
        if (menu.getStatus() == null) {
            menu.setStatus(1);
        }
        
        menuMapper.insert(menu);

        // 如果是CONTENT类型且有内容详情，保存内容详情
        if ("CONTENT".equals(menuDTO.getType()) && menuDTO.getContentDetails() != null) {
            MenuContent menuContent = new MenuContent();
            BeanUtils.copyProperties(menuDTO.getContentDetails(), menuContent);
            menuContent.setMenuId(menu.getId());
            menuMapper.insertContent(menuContent);
        }

        // 记录详细操作日志
        operationLogService.saveDetail(OperationLogUtils.buildCreateLog(
                "menu", menu.getId(), menu.getName(), menu));

        return menu;
    }

    @Override
    @Transactional
    public void update(Long id, MenuDTO menuDTO) {
        Menu existingMenu = getById(id);

        // 保存更新前的数据
        Menu oldMenu = new Menu();
        BeanUtils.copyProperties(existingMenu, oldMenu);

        // 更新菜单基本信息
        Menu menu = new Menu();
        menu.setId(id);
        menu.setType(menuDTO.getType());
        menu.setName(menuDTO.getName());
        menu.setDescription(menuDTO.getDescription());
        menu.setSortOrder(menuDTO.getSortOrder());
        menu.setStatus(menuDTO.getStatus());
        menu.setHomeImage(menuDTO.getHomeImage());
        menuMapper.update(menu);

        // 如果是CONTENT类型，更新内容详情
        if ("CONTENT".equals(existingMenu.getType()) && menuDTO.getContentDetails() != null) {
            MenuContent existingContent = menuMapper.getContentByMenuId(id);
            if (existingContent != null) {
                // 更新现有内容
                MenuContent menuContent = new MenuContent();
                BeanUtils.copyProperties(menuDTO.getContentDetails(), menuContent);
                menuContent.setMenuId(id);
                menuMapper.updateContent(menuContent);
            } else {
                // 创建新的内容详情
                MenuContent menuContent = new MenuContent();
                BeanUtils.copyProperties(menuDTO.getContentDetails(), menuContent);
                menuContent.setMenuId(id);
                menuMapper.insertContent(menuContent);
            }

        }

        // 记录详细操作日志
        operationLogService.saveDetail(OperationLogUtils.buildUpdateLog(
                "menu", id, existingMenu.getName(), oldMenu, menu));
    }

    @Override
    @Transactional
    public void deleteById(Long id) {
        Menu menu = getById(id);

        // 检查是否有子菜单
        int childCount = menuMapper.countByParentId(id);
        if (childCount > 0) {
            throw new BaseException("存在子菜单，无法删除");
        }

        // 删除菜单内容详情
        if ("CONTENT".equals(menu.getType())) {
            menuMapper.deleteContentByMenuId(id);
        }

        // 删除菜单
        menuMapper.deleteById(id);

        // 记录详细操作日志
        operationLogService.saveDetail(OperationLogUtils.buildDeleteLog(
                "menu", id, menu.getName(), menu));
    }

    @Override
    @Transactional
    public void importMenus(MultipartFile file) {
        try {
            List<List<String>> data = ExcelUtil.readExcel(file.getInputStream());

            if (data.isEmpty()) {
                throw new BaseException("Excel文件为空");
            }
            if (data.size() < 4) {
                throw new BaseException("请包含表头和至少一行数据");
            }
            
            int successCount = 0;
            List<String> importedMenus = new ArrayList<>();
            
            for (int i = 3; i < data.size(); i++) {
                List<String> row = data.get(i);
                
                // 确保行数据完整性
                if (row.size() < 10) {
                    log.warn("第{}行数据不完整，跳过处理", i + 1);
                    continue;
                }
                
                try {
                    String processedMenus = processMenuRow(row, i);
                    if (processedMenus != null && !processedMenus.isEmpty()) {
                        successCount++;
                        importedMenus.add(processedMenus);
                    }
                } catch (Exception e) {
                    log.error("处理第{}行数据时发生错误: {}", i + 1, e.getMessage(), e);
                    throw new BaseException("处理第" + (i + 1) + "行数据时发生错误: " + e.getMessage());
                }
            }

            // 记录批量导入日志
            operationLogService.saveDetail(OperationLogUtils.buildCustomLog(
                    "IMPORT", 
                    String.format("批量导入菜单：成功导入 %d 行数据，创建的菜单包括：%s", 
                            successCount, String.join("、", importedMenus)), 
                    "menu", 
                    null, 
                    file.getOriginalFilename()));

        } catch (IOException e) {
            throw new BaseException("文件读取失败");
        }
    }
    
    /**
     * 处理单行菜单数据
     * @return 返回创建的菜单描述信息，用于日志记录
     */
    private String processMenuRow(List<String> row, int rowIndex) {
        String firstMenuName = row.get(0) != null ? row.get(0).trim() : "";
        String secondMenuName = row.get(1) != null ? row.get(1).trim() : "";
        String thirdMenuName = row.get(2) != null ? row.get(2).trim() : "";
        
        List<String> createdMenus = new ArrayList<>();
        
        // 如果一级菜单名为空，跳过这行
        if (firstMenuName.isEmpty()) {
            return null;
        }
        
        // 1. 处理一级菜单
        boolean isFirstMenuNew = !menuExists(firstMenuName, null);
        Menu firstMenu = findOrCreateMenu(firstMenuName, "MENU", null);
        if (isFirstMenuNew) {
            createdMenus.add(firstMenuName + "(一级)");
        }
        
        // 2. 判断是否需要创建二级菜单
        Menu parentMenu = firstMenu;
        
        if (!secondMenuName.isEmpty() && !thirdMenuName.isEmpty() && !"/".equals(thirdMenuName)) {
            // 需要创建二级菜单，三级菜单为内容项
            boolean isSecondMenuNew = !menuExists(secondMenuName, firstMenu.getId());
            Menu secondMenu = findOrCreateMenu(secondMenuName, "SUBMENU", firstMenu.getId());
            if (isSecondMenuNew) {
                createdMenus.add(secondMenuName + "(二级)");
            }
            parentMenu = secondMenu;
        } else if (!secondMenuName.isEmpty()) {
            // 二级菜单就是内容项，使用二级菜单名作为内容项名
            thirdMenuName = secondMenuName;
        }
        
        // 3. 创建内容项
        if (!thirdMenuName.isEmpty() && !"/".equals(thirdMenuName)) {
            boolean contentCreated = createContentMenu(thirdMenuName, parentMenu.getId(), row, rowIndex);
            if (contentCreated) {
                createdMenus.add(thirdMenuName + "(内容项)");
            }
        }
        
        return createdMenus.isEmpty() ? null : String.join("、", createdMenus);
    }
    
    /**
     * 检查菜单是否存在
     */
    private boolean menuExists(String menuName, Long parentId) {
        Menu existingMenu = menuMapper.findByNameAndParentId(menuName, parentId);
        return existingMenu != null;
    }
    
    /**
     * 查找或创建菜单
     */
    private Menu findOrCreateMenu(String menuName, String menuType, Long parentId) {
        // 先查找是否存在
        Menu existingMenu = menuMapper.findByNameAndParentId(menuName, parentId);
        if (existingMenu != null) {
            return existingMenu;
        }
        
        // 不存在则创建
        Menu menu = new Menu();
        menu.setName(menuName);
        menu.setType(menuType);
        menu.setParentId(parentId);
        menu.setSortOrder(0);
        menu.setStatus(1);
        
        menuMapper.insert(menu);
        
        log.info("创建{}菜单: {}", menuType, menuName);
        return menu;
    }
    
    /**
     * 创建内容项菜单
     * @return 返回是否成功创建了新的内容项
     */
    private boolean createContentMenu(String contentName, Long parentId, List<String> row, int rowIndex) {
        // 检查内容项是否已存在
        Menu existingContent = menuMapper.findByNameAndParentId(contentName, parentId);
        if (existingContent != null) {
            log.warn("内容项 {} 已存在，跳过创建", contentName);
            return false;
        }
        
        // 创建内容项菜单
        Menu contentMenu = new Menu();
        contentMenu.setName(contentName);
        contentMenu.setType("CONTENT");
        contentMenu.setParentId(parentId);
        contentMenu.setSortOrder(0);
        contentMenu.setStatus(1);
        
        menuMapper.insert(contentMenu);
        
        // 创建内容详情
        MenuContent menuContent = new MenuContent();
        menuContent.setMenuId(contentMenu.getId());
        
        // 处理各个字段
        menuContent.setServiceTarget(getStringValue(row, 3));        // 服务对象
        menuContent.setPolicyStandard(getStringValue(row, 4));       // 政策（服务）标准
        menuContent.setDepartment(getStringValue(row, 5));           // 办理科室
        menuContent.setContact(getStringValue(row, 6));              // 联系方式
        menuContent.setMiniProgramCode1(getStringValue(row, 7));              // 小程序码1
        menuContent.setMiniProgramCode2(getStringValue(row, 8));              // 小程序码2
        menuContent.setHandleLink(getStringValue(row, 9));           // 办理链接
        
        // 处理二维码字段
        String qrCodeValue = getStringValue(row, 10);
        if (!qrCodeValue.isEmpty()) {
            // 如果是Excel图片函数，返回空字符串
            if (qrCodeValue.contains("_xlfn.DISPIMG")) {
                menuContent.setQrCode("");
            } else {
                menuContent.setQrCode(qrCodeValue);
            }
        }
        menuContent.setOtherInfo(getStringValue(row, 11));            // 其他展示信息
        
        menuMapper.insertContent(menuContent);
        
        log.info("创建内容项: {} 及其详细信息", contentName);
        return true;
    }
    
    /**
     * 安全获取字符串值
     */
    private String getStringValue(List<String> row, int index) {
        if (index < row.size() && row.get(index) != null) {
            return row.get(index).trim();
        }
        return "";
    }

    /**
     * 验证菜单层级限制
     */
    private void validateMenuLevel(Menu parentMenu, String childType) {
        String parentType = parentMenu.getType();
        
        // 业务规则验证
        if ("MENU".equals(parentType)) {
            // 一级菜单只能包含二级菜单和内容项
            if (!"SUBMENU".equals(childType) && !"CONTENT".equals(childType)) {
                throw new BaseException("一级菜单只能包含二级菜单和内容项");
            }
        } else if ("SUBMENU".equals(parentType)) {
            // 二级菜单只能包含内容项
            if (!"CONTENT".equals(childType)) {
                throw new BaseException("二级菜单只能包含内容项");
            }
        } else if ("CONTENT".equals(parentType)) {
            // 内容项不能包含子项
            throw new BaseException("内容项不能包含子项");
        }
    }
    
    @Override
    public List<Menu> getTopLevelMenus() {
        log.info("获取顶级菜单列表");
        return menuMapper.getTopLevelMenus();
    }
    
    @Override
    public List<Menu> getChildMenusByParentId(Long parentId) {
        log.info("根据父ID获取所有子菜单列表（递归）：{}", parentId);
        // 验证父菜单是否存在
        Menu parentMenu = menuMapper.getById(parentId);
        if (parentMenu == null) {
            throw new BaseException("父菜单不存在");
        }
        
        // 递归获取所有子菜单
        List<Menu> allChildren = new ArrayList<>();
        getAllChildrenRecursively(parentId, allChildren);
        
        // 按sort_order排序
        allChildren.sort((a, b) -> {
            int sortA = a.getSortOrder() != null ? a.getSortOrder() : 0;
            int sortB = b.getSortOrder() != null ? b.getSortOrder() : 0;
            if (sortA != sortB) {
                return Integer.compare(sortB, sortA); // 降序
            }
            return a.getCreateTime().compareTo(b.getCreateTime()); // 升序
        });
        
        return allChildren;
    }
    
    /**
     * 递归获取所有子菜单
     */
    private void getAllChildrenRecursively(Long parentId, List<Menu> result) {
        // 获取直接子菜单
        List<Menu> directChildren = menuMapper.getChildMenusByParentId(parentId);
        
        for (Menu child : directChildren) {
            result.add(child);
            // 递归获取子菜单的子菜单
            getAllChildrenRecursively(child.getId(), result);
        }
    }
    
    @Override
    public MenuContentDetailVO getContentDetailById(Long id) {
        log.info("根据ID获取内容项详情和顶层父级信息：{}", id);
        
        // 1. 获取菜单基本信息
        Menu menu = getById(id);
        
        // 2. 创建返回对象
        MenuContentDetailVO result = new MenuContentDetailVO();
        BeanUtils.copyProperties(menu, result);
        
        // 3. 如果是内容项，获取内容详情
        if ("CONTENT".equals(menu.getType())) {
            MenuContent content = menuMapper.getContentByMenuId(id);
            result.setContentDetails(content);
        }

        // 4. 获取父级菜单信息
        if (menu.getParentId() != null){
            Menu parentMenu = getById(menu.getParentId());
            result.setParentName(parentMenu.getName());
        }
        
        // 5. 获取顶层父级菜单信息
        Menu topParent = findTopParentMenu(menu);
        result.setTopParentName(topParent.getName());
        result.setTopParentId(topParent.getId());
        
        return result;
    }
    
    /**
     * 递归查找顶层父级菜单
     */
    private Menu findTopParentMenu(Menu menu) {
        if (menu.getParentId() == null) {
            // 当前菜单就是顶层菜单
            return menu;
        }
        
        // 获取父级菜单
        Menu parentMenu = menuMapper.getById(menu.getParentId());
        if (parentMenu == null) {
            // 父级菜单不存在，返回当前菜单
            return menu;
        }
        
        // 递归查找父级的父级
        return findTopParentMenu(parentMenu);
    }
}
